package com.sprucetec.live.util;

import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import com.sprucetec.live.common.exceptioin.SprucetecException;
import lombok.extern.slf4j.Slf4j;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.Map;

/**
 * @Author Wangshaobo
 * @Description  pdf处理类
 * @Date 2018/12/18 17:14
 */
@Slf4j
public class PdfUtils {
    private PdfUtils() {
    }

    /**
     * PDF 预览
     * @param groupTemplate beetl核心 加载模板
     * @param templateName 模板名称
     * @param variables 参数
     * @param response HttpServletResponse
     */
    public static void preview(GroupTemplate groupTemplate, String templateName, Map<String, Object> variables, HttpServletResponse response) {
        try (ServletOutputStream out = response.getOutputStream()) {
            generateAll(groupTemplate, templateName, out, variables);
            out.flush();
        } catch (Exception e) {
            log.error("PDF预览异常",e);
            throw new SprucetecException("PDF预览异常："+e.getMessage());
        }
    }

    /**
     * 根据模板，生成pdf文档
     * @param groupTemplate beetl 核心 模板加载
     * @param templateName
     * @param out
     * @param variables
     * @throws IOException
     * @throws DocumentException
     */
    private static void generateAll(GroupTemplate groupTemplate, String templateName, ServletOutputStream out, Map<String, Object> variables) throws IOException, DocumentException {
        if (CollectionUtils.isEmpty(variables)) {
            log.warn("警告:beetl模板参数为空!");
            return;
        }


        ITextRenderer renderer = new ITextRenderer();
        renderer.getSharedContext().setReplacedElementFactory(new Base64ImgReplacedElementFactory());
        renderer.getSharedContext().getTextRenderer().setSmoothingThreshold(0);
        Document doc = generateDoc(groupTemplate, templateName, variables);
        renderer.setDocument(doc, null);
        //设置字符集(宋体),此处必须与模板中的<body style="font-family: SimSun">一致,区分大小写,不能写成汉字"宋体"
        ITextFontResolver fontResolver = renderer.getFontResolver();
        if ("linux".equals(getCurrentOperatingSystem())) {
            fontResolver.addFont("/usr/share/fonts/chinese/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        } else if (getCurrentOperatingSystem().contains("windows")) {
            fontResolver.addFont("c:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        }
        //展现和输出pdf
        renderer.layout();
        renderer.createPDF(out);
        //根据参数集个数循环调用模板,追加到同一个pdf文档中
        //(注意:此处从1开始,因为第0是创建pdf,从1往后则向pdf中追加内容)
        /*for (int i = 1; i < listVars.size(); i++) {
            Document docAppend = generateDoc(configurer, templateName, listVars.get(i));
            renderer.setDocument(docAppend, null);
            renderer.layout();
            renderer.writeNextDocument(); //写下一个pdf页面
        }*/
        renderer.finishPDF();
    }

    /**
     * 按模板和参数生成html字符串,再转换为flying-saucer识别的Document
     * @param groupTemplate beetl核心 模板加载
     * @param templateName 模板名称
     * @param variables 参数
     * @return
     */
    private static Document generateDoc(GroupTemplate groupTemplate, String templateName, Map<String, Object> variables) {
        Template template = groupTemplate.getTemplate(templateName);
        StringWriter stringWriter = new StringWriter();
        try (BufferedWriter writer = new BufferedWriter(stringWriter)) {
            try {
                //绑定参数
                template.fastBinding(variables);
                //写入流
                template.renderTo(writer);
                writer.flush();
            } catch (IOException e) {
                log.error("IO异常", e);
                throw new SprucetecException("IO异常");
            }
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            return builder.parse(new ByteArrayInputStream(stringWriter.toString().getBytes()));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new SprucetecException("beetl模板生成html失败:"+e.getMessage());
        }
    }


    /**
     * pdf下载
     *
     * @param groupTemplate  beetl核心 加载模板
     * @param templateName 模板名称(带后缀.ftl)
     * @param variables     模板参数集
     * @param response     HttpServletResponse
     * @param fileName     下载文件名称(带文件扩展名后缀)
     */
    public static void download(GroupTemplate groupTemplate, String templateName, Map<String, Object> variables, HttpServletResponse response, String fileName) {
        // 设置编码、文件ContentType类型、文件头、下载文件名
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" +
                    new String(fileName.getBytes("gb2312"), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
        }
        try (ServletOutputStream out = response.getOutputStream()) {
            generateAll(groupTemplate, templateName, out, variables);
            out.flush();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new SprucetecException("pdf下载出错:"+e.getMessage());
        }
    }

    public static String getCurrentOperatingSystem(){
        String os = System.getProperty("os.name").toLowerCase();
        System.out.println("---------当前操作系统是-----------" + os);
        return os;
    }

}
